/*
 * @author: Duo Ji
 */
package com.server.cm;

import java.util.Date;
import java.util.Vector;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicLong;

import com.data.Device;
import com.data.Request;
import com.data.SourceType;
import com.data.User;
import com.server.dao.JDBCUserDAO;
import com.server.dao.UserDAO;
import com.util.Debug;

/**
 * The Class Scheduler.
 */
public class Scheduler implements Runnable {

	/** The _request q. */
	ConcurrentLinkedQueue<Request> _requestQ;

	/** The _interval. */
	int _interval;

	/** The _request id. */
	AtomicLong _requestId;

	/**
	 * Instantiates a new scheduler.
	 * 
	 * @param q
	 *            the q
	 * @param interval
	 *            the interval
	 * @param requestId
	 *            the request id
	 */
	public Scheduler(ConcurrentLinkedQueue<Request> q, int interval, AtomicLong requestId) {
		_requestQ = q;
		_interval = interval;
		_requestId = requestId;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Runnable#run()
	 */
	public void run() {
		Debug.println("start Scheduler.run() interval = " + _interval);

		// TODO may have to change the UserDAO initialization
		
		UserDAO udao = new JDBCUserDAO();
		
		Vector<User> v = udao.getUsersByInterval(_interval);
		
		if (v == null) {
			System.out.println("No user found with retrieval interval " + _interval);
			return;
		}

		Debug.println("iterate through " + v.size() + " users");
		// iterate through users, getting all devices and create requests
		for (int i = 0; i < v.size(); i++) {
			// for each users, get requests for all devices
			Vector<Request> rs = getRequests(v.get(i));
			for (int j = 0; j < rs.size(); j++) {
				// for each device,
				Debug.println("add a request to queue");
				_requestQ.add(rs.get(j));
				if (j == 0) {
					// notify NotificationManager as soon as there is request object in the queue
					synchronized (_requestQ) {
						_requestQ.notify();
						Debug.println("Scheduler with interval " + _interval + " called q.notify");
					}
				}
			}
			// notify again, jsut to be sure
			synchronized (_requestQ) {
				_requestQ.notify();
				Debug.println("Scheduler with interval " + _interval + " called q.notify");
			}
		}
	}

	/**
	 * Gets the requests for a user.
	 * 
	 * @param u
	 *            the u
	 * @return the requests
	 */
	private Vector<Request> getRequests(User u) {
		Debug.println("Scheduler.getRequests()");
		Vector<Request> rtnVal = new Vector<Request>();
		Vector<Device> devices = u.getDevice();
		for (int i = 0; i < devices.size(); i++) {
			Debug.println("iterating through " + devices.size() + " devices");
			Device d = devices.get(i);
			// we need to create a request for each device this user has
			Request r = new Request(_requestId.getAndIncrement(), u.getId(), u.getPwd(), SourceType.scheduler, new Date());
			r.setPlatform(d.getPlatform());
			r.setDeviceInfo(d.getDeviceInfo());
			rtnVal.add(r);
		}
		Debug.println("getRequests() returning " + rtnVal.size() + " requests");
		return rtnVal;
	}

}
